package com.ztesoft.web.checkup;

import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

import javax.sql.DataSource;

import org.springframework.jdbc.core.JdbcTemplate;

import com.ztesoft.core.db.ds.DynamicDataSourceManager;
import com.ztesoft.core.spring.context.SpringApplicationContextHolder;
import com.ztesoft.framework.log.ZTEsoftLogManager;
import com.ztesoft.framework.util.DateUtils;
import com.ztesoft.web.baseconfig.db.po.DmPlanPO;
import com.ztesoft.web.baseconfig.db.po.DmSrcTablePO;
import com.ztesoft.web.baseconfig.db.po.DmStrategyPO;
import com.ztesoft.web.checkup.service.CheckUpTaskService;
import com.ztesoft.web.common.DMSConstant;
import com.ztesoft.web.common.customdb.dao.DmTaskStageCustomDao;
import com.ztesoft.web.common.customdb.dao.DmTaskStageDefineCustomDao;
import com.ztesoft.web.common.customdb.dao.dto.DmTaskStageDto;
import com.ztesoft.web.common.db.arg.DmArg;
import com.ztesoft.web.common.db.dao.DmDao;
import com.ztesoft.web.syncbaseinfo.service.BaseInfoService;
import com.ztesoft.web.syncbaseinfo.service.impl.BaseInfoServiceImpl;
import com.ztesoft.web.taskgenerator.db.dao.DmTaskDao;
import com.ztesoft.web.taskgenerator.db.po.DmTaskPO;
import com.ztesoft.web.taskgenerator.db.po.DmTaskStageDefinePO;

/**
 * 体检处理
 * 
 * @author lin.weibin@zte.com.cn
 * @date 2015年8月11日
 */
public class CheckUpTask implements Callable<DmTaskStageDto> {
	
	private static final ZTEsoftLogManager LOGGER = ZTEsoftLogManager.getLogger(CheckUpTask.class);

	private DmTaskStageDto taskStagePO;//分表
	
	private DmSrcTablePO dmSrcTablePO;//主表
	
	private DmPlanPO planPO;
	
	private String sqlStr;//扫描SQL
	
	private int taskId;
	
	private DmStrategyPO strategyPO;

	private DataSource ds;
	
	private DmTaskStageCustomDao taskStageCustomDao;
	
	private DynamicDataSourceManager dynamicDataSourceManager;

	private DmTaskStageDefineCustomDao taskStageDefineDao;
	
	private CheckUpTaskService checkUpTaskService;
	
	private BaseInfoService baseInfoService;
	
	private DmDao dmDao;
	
	private String[] dbConfig;
	
	private DmTaskDao taskDao;
	
	public CheckUpTask(String sqlStr, DmSrcTablePO dmSrcTablePO, DmTaskStageDto taskStagePO, int taskId, 
			DmStrategyPO strategyPO, DmPlanPO planPO, String[] dbConfig) {
		this.planPO = planPO;
		this.sqlStr = sqlStr;
		this.taskStagePO = taskStagePO;
		this.dmSrcTablePO = dmSrcTablePO;
		this.strategyPO = strategyPO;
		this.taskId = taskId;
		this.dbConfig = dbConfig;
		dmDao = SpringApplicationContextHolder.getBean(DmDao.class);
		taskDao = SpringApplicationContextHolder.getBean(DmTaskDao.class);
		checkUpTaskService = (CheckUpTaskService) SpringApplicationContextHolder.getBean("CheckUpTaskServiceImpl");
		taskStageCustomDao = (DmTaskStageCustomDao) SpringApplicationContextHolder.getBean("TaskStageCustomDao");
		dynamicDataSourceManager = (DynamicDataSourceManager) SpringApplicationContextHolder.getBean("dynamicDataSourceManager");
		taskStageDefineDao = (DmTaskStageDefineCustomDao) SpringApplicationContextHolder.getBean("TaskStageDefineCustomDao");
		baseInfoService = SpringApplicationContextHolder.getBean(BaseInfoServiceImpl.class);
		ds = dynamicDataSourceManager.getDruidDataSource(dmSrcTablePO.getDbLinkId()+dmSrcTablePO.getDbUserName(), dbConfig);
	}
	

	@Override
	public DmTaskStageDto call() {
		//
		taskStagePO.setTaskStartTime((taskStagePO.getTaskStartTime()!=null)?null:DateUtils.getDBCurrentTime());
		taskStagePO.setState(DMSConstant.Status.PROCESSING.getState());
		taskStagePO.setTaskEndTime(null);//避免带入条件
		taskStagePO.setCheckDataSize(null);
		taskStagePO.setErrorDesc(null);
		taskStageCustomDao.updateTaskStageState(taskStagePO);//
		
		return addTask();
	}
	
	private DmTaskStageDto addTask() {
		int resultCount = 0;//结果数据
		List<Map<String, Object>> list = null;
		String checkState = null;
		String state = null;
		DmTaskStageDefinePO taskStageDefinePO = taskStageDefineDao.selectTaskStage(planPO.getOperType(), 
				DMSConstant.STAGE_CHECKUP, null);
		if ("F".equals(taskStageDefinePO.getIsLastStage())) {			
			taskStageDefinePO = taskStageDefineDao.selectTaskStage(planPO.getOperType(), null, 
					taskStageDefinePO.getPriority()+1);
		}
		if (null == taskStageDefinePO.getStage() || DMSConstant.STAGE_CHECKUP == taskStageDefinePO.getStage()) {//
			state = DMSConstant.Status.SUCCESS.getState();//已完成
			LOGGER.info(Thread.currentThread()+"只有体检环节不需要子任务");
			DmTaskPO taskPO = new DmTaskPO();
			taskPO.setDmTaskId(taskId);
			taskPO.setNeedSubtask(DMSConstant.NEED_SUBTASK_F);
			taskPO.setStateDate(DateUtils.getDBCurrentTime());
			taskDao.updateByPrimaryKey(taskPO);
			taskStagePO.setCheckCount(taskStagePO.getTotalRecordCount());
			taskStagePO.setCheckDataSize(taskStagePO.getTotalDataSize());
			taskStagePO.setTaskStartTime(DateUtils.getDBCurrentTime());
			taskStageCustomDao.updateTaskStageCheckCount(taskStagePO);
			taskStagePO.setCheckState(DMSConstant.SUCCESS);
			return taskStagePO;
		} else if (DMSConstant.STAGE_BACKUP == taskStageDefinePO.getStage()) {
			state = DMSConstant.Status.TOBACKUP.getState();//待备份
		} else if (DMSConstant.STAGE_CLEANUP == taskStageDefinePO.getStage()) {
			state = DMSConstant.Status.TOCLEANUP.getState();//待清理
		}
		//分页查询
		int length = taskStagePO.getTotalRecordCount();//list.size();
		int batchInt = strategyPO.getBatchCommitCount();//每批次提交记录数
		int steps = (length % batchInt == 0) ? (length / batchInt) : (length / batchInt + 1);
		int arg0 = 0,arg1 = 0;
		for (int i = 1; i <= steps; i++) {
			if (list != null) list.clear();
			if (DMSConstant.ORACLE.equals(dbConfig[0])) {//oracle
				arg0 = i*batchInt;
				arg1 = (i-1)*batchInt+1;
			} else if (DMSConstant.MYSQL.equals(dbConfig[0])) {//mysql
				arg0 = (i-1)*batchInt;
				arg1 = batchInt;
			} else if (DMSConstant.INFORMIX.equals(dbConfig[0])) {//informix
				arg0 = (i-1)*batchInt;
				arg1 = batchInt;
			} else if (DMSConstant.MDB.equals(dbConfig[0])) {
			}
			
			LOGGER.debug("|||分页查询||::PAGE_SQL_STR:{0},condition:{1},{2}",sqlStr, arg0, arg1);
			list = new JdbcTemplate(ds).queryForList(sqlStr, arg0, arg1);
			LOGGER.debug("|||分页查询成功||");
			try {
				resultCount += checkUpTaskService.addCheckUp(list, state, strategyPO, taskId, dmSrcTablePO, taskStagePO);
				taskStagePO.setCheckCount(resultCount);
			} catch (Exception e) {
				LOGGER.error("|||分页查询||::PAGE_SQL_STR:{0},condition:{1},{2}",sqlStr, arg0, arg1);
				LOGGER.error("checkup error:",e);
				taskStagePO.setCheckState(DMSConstant.FAIL);
				taskStagePO.setErrorDesc(e.getMessage());//
			    DmArg arg = new DmArg();
			    DmArg.DmCriteria criteria = arg.createCriteria();
			    criteria.andDmTaskIdEqualTo(taskStagePO.getDmTaskId());
			    criteria.andDmStrategyIdEqualTo(taskStagePO.getDmStrategyId());
			    criteria.andStateEqualTo(DMSConstant.Status.TOBACKUP.toString());
			    dmDao.deleteByArg("DM_"+taskStagePO.getCheckObjName(), arg);
				return taskStagePO;
			}
			
			/*
			 * 暂停、取消判断
			 */
			checkState = baseInfoService.doCheck(taskStagePO, planPO);
			LOGGER.info("暂停、取消判断,当前系统状态：{0},检测结果：{1}",DMSConstant.taskInstList.get(taskStagePO.getDmTaskId()).getStatus(),checkState);
			if (checkState != null) {
				taskStagePO.setCheckState(checkState);
				if (DMSConstant.Status.CANCEL.getState().equals(checkState)){
				    DmArg arg = new DmArg();
				    DmArg.DmCriteria criteria = arg.createCriteria();
				    criteria.andDmTaskIdEqualTo(taskStagePO.getDmTaskId());
				    criteria.andDmStrategyIdEqualTo(taskStagePO.getDmStrategyId());
				    criteria.andStateEqualTo(DMSConstant.Status.TOBACKUP.toString());
				    dmDao.deleteByArg("DM_"+taskStagePO.getCheckObjName(), arg);
				}
				return taskStagePO;
				
			}
		}
		
		taskStagePO.setCheckState(DMSConstant.SUCCESS);
		return taskStagePO;
	}


}
